﻿<!DOCTYPE html>
<html>
<head>
    <title>CGI</title>
</head>
<body>
    <h1>Our Page</h1>
    <script>
        //01

        var addTo = function (passed) {
            var inner = 2;
            return passed + inner;
        };

        console.log(addTo(3));

        //In JS variables are defined outside the function are automatically available inside
        //JS use laxical scoping, inner not accessible outside, but outside accessible inside, this is possible with closure
        //technically any function using variable outside the scope, is a closure
        //var passed = 3;
        //var addTo = function () {
        //    var inner = 2;
        //    return passed + inner;
        //};

        //console.log(addTo());
        ////console.dir(addTo);

        //02
        /*
        //within "addTo"function, we have another function "add" which returns a value and "addTo" return the function "add" itself

        var addTo = function (passed) {
            var add = function (inner) {
                return passed + inner;
            };
            return add;
        };

        addTo(3);
        //it's has a closure, which preserve the value inside
        //console.dir(addTo(3));

        //var addThree = addTo(3);
        //var addFour = addTo(4);
        //console.dir(addThree);
        //console.dir(addFour);

        //now pass inner
        //as many as function can call throug closure, it's preserve the value inside the function as property
        //closures are nothing but functions with preserve data
        //console.log(addThree(1));
        //console.log(addFour(1));
        */

        //03
        //sometimes we want functions to persist, want to use same function over and over, even already called it
        //not only function to exist but entire context to be exist (all of the variables and it's parent functions)
        //we set here "salaryUpdater" to a function
        //setting currentSalary to salary
        //we also setting "generator",which itself a function
        //we also return the generator
        //closure are as a functions that persist
        //function are like object in JS, they created,they have life cycle and they are garbage collected
        //through closure we want to persist that garbage collector, we want to hold down the function
        /*
        var salaryUpdater = function (salary) {
            var currentSalary = salary;
            var generator = function () {
                currentSalary *= 2;
                return currentSalary;
            };
            return generator;
        };
        //"salaryUpdater" gets called and internal functions gets returened
        //updateFn is closure and points back to "generator" function, we can access the context of functions, we have access to "currentSalary"
        var updateFn = salaryUpdater(50000);
        console.dir(updateFn);
        console.log(updateFn());
        //here "updateFn" going to persist along with "currentSalary" = 50000
         */

        //04
        //here we do have a closure and currentSalary is persisting
        /*
        var salaryUpdater = function (salary) {
            var currentSalary = salary;
            var generator = function () {
                currentSalary += 10000;
                return currentSalary;
            };
            return generator;
        };
        var updateFn = salaryUpdater(50000);
        updateFn();
        console.log(updateFn());
        */
    </script>
</body>
</html>